package cn.credit.loan.shiro;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import net.sf.ehcache.CacheManager;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.io.ResourceUtils;
import org.apache.shiro.mgt.SecurityManager;
/**
 * SpringBoot+shiro权限框架的配置
 * @author
 *
 */

@Configuration
public class ShiroConfiguration {
	
	/**
	 * 
	 * @param securityManager
	 * @return
	 */
	 @Bean
	 public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
		//1.创建ShiroFilterFactoryBean对象
		ShiroFilterFactoryBean  shiroFilterFactoryBean=new ShiroFilterFactoryBean();
		//2.设置SecurityManager;
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		//3.配置拦截器.使用Map进行配置：LinkedHashMap ，LinkedHashMap是有序的，shiro会根据添加的顺序进行拦截。
		Map<String,String> filterChainMap=new LinkedHashMap<String,String>();
		
		//配置退出.过滤器：loginout,这个由shiro进行实现的
		filterChainMap.put("/loginout","logout");
		//authc : 所有的URL都必须认证通过才可以访问
		filterChainMap.put("/**","authc");
		//表示可以匿名访问
		filterChainMap.put("/**", "anon"); 
		//设置默认登录的URL
		shiroFilterFactoryBean.setLoginUrl("/userlogin");
		//设置成功之后要跳转的URL路径链接
		shiroFilterFactoryBean.setSuccessUrl("front/home");
		//未授权界面
		shiroFilterFactoryBean.setUnauthorizedUrl("/403");
		
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
		
		return shiroFilterFactoryBean;
	}
	 
	/**
	 * 定义Shiro的安全管理器
	 * @return
	 */
	@Bean
	public SecurityManager securityManager(UserReaml userReaml){
		DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
		securityManager.setRealm(userReaml);
		// //注入ehcache缓存管理器;
		securityManager.setCacheManager(ehCacheManager());
		//注入Cookie记住我管理器
		securityManager.setRememberMeManager(rememberMeManager());
		return securityManager;
	}
	
	/**
	 * 自定义 UserReaml 用户
	 * @param hashedCredentialsMatcher
	 * @return
	 */
	@Bean
	public UserReaml userReaml(HashedCredentialsMatcher hashedCredentialsMatcher){
		UserReaml userReaml = new UserReaml();
		userReaml.setCredentialsMatcher(hashedCredentialsMatcher);
		return userReaml;
		
	}

	/**
	 * 凭证匹配器
	 * @return
	 */
	@Bean
	public HashedCredentialsMatcher hashedCredentialsMatcher(){
		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
		hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
		hashedCredentialsMatcher.setHashIterations(1);//散列的次数，比如散列1次，相当于 md5(md5(""));
		return hashedCredentialsMatcher;
	}
	/**
	 * ehcache缓存管理器；shiro整合ehcache：
	 * 通过安全管理器：securityManager
	 * 单例的cache防止热部署重启失败
	 * shiro整合ehcache缓存：ShiroConfiguration.getEhCacheManager()
	 * @return EhCacheManager
	 */
	@Bean 
	public EhCacheManager ehCacheManager() {
		EhCacheManager ehcache = new EhCacheManager();
		CacheManager cacheManager = CacheManager.getCacheManager("es");
		  if(cacheManager == null){
			  try {
					  cacheManager = CacheManager.create(ResourceUtils.getInputStreamForPath("classpath:config/ehcache.xml"));
			  } catch (CacheException | IOException e) {
					e.printStackTrace();
			  }
		  }
		ehcache.setCacheManager(cacheManager);
		return ehcache;
	}
	/**
	 * 设置记住我cookie过期时间
	 * @return
	 */
	@Bean
	public SimpleCookie remeberMeCookie(){
		//cookie名称;对应前端的checkbox的name = rememberMe
		SimpleCookie scookie=new SimpleCookie("rememberMe");
		//记住我cookie生效时间30天 ,单位秒  [1小时]
		scookie.setMaxAge(3600);
		return scookie;
	}
	/**
	 * 配置cookie记住我管理器
	 * @return
	 */
	@Bean
	public CookieRememberMeManager rememberMeManager(){
		CookieRememberMeManager cookieRememberMeManager=new CookieRememberMeManager();
		cookieRememberMeManager.setCookie(remeberMeCookie());
		return cookieRememberMeManager;
	}
}
